#include "Mandelbrot.h"
#include "Parameters.h"

#include <iostream>

Mandelbrot::Mandelbrot() : SpriteWidth(Parameters::GetScreenWidth()),
                           SpriteHeight(Parameters::GetScreenHeight()),
                           pixelArray_(0), iterations_(0), depth_(255)  {}

void Mandelbrot::Allocate()
{
    pixelArray_ = new uint8_t[4 * SpriteWidth * SpriteHeight];
    iterations_ = new int[SpriteWidth * SpriteHeight];

    //set r, g, b = 0 and a = 255;
    for (int i = 0; i < 4 * SpriteWidth * SpriteHeight; i += 4)
    {
        for (int j = 0; j < 3; j++)
        {
            pixelArray_[i + j] = 0;
        }

        pixelArray_[i + 3] = 255;
    }

    for (int i = 0; i < SpriteWidth * SpriteHeight; i++)
        iterations_[i] = 0;
}

void Mandelbrot::Deallocate()
{
    delete [] pixelArray_;
    delete [] iterations_;
}

void Mandelbrot::Iterate()
{
    double x, y, x_0, y_0, xtemp;
    for (int i = 0; i < SpriteWidth * SpriteHeight; i++)
    {
        //complex plane coordinates for pixel
        x_0 = -2.5 + 3.5 / SpriteWidth * GetColumn(i);
        y_0 = -1.0 + 2.0 / SpriteHeight * GetRow(i);

        x = y = 0;
        while (x * x + y * y < 4 && ++iterations_[i] < depth_)
        {
            //complex squaring
            xtemp = x * x - y * y + x_0;
            y = 2 * x * y + y_0;
            x = xtemp;
        }
    }

    std::cout << SpriteHeight * SpriteWidth << std::endl;

    //Do the coloring.
    //first, create a pixel count histogram
    int* pixelCount = new int[depth_];
    float* pixelHist = new float[depth_];
    for (int i = 0; i < 70000; i++)
        pixelCount[iterations_[i]]++;

    int sum = 0;
    for (int i = 0; i < depth_; i++)
    {
        sum += pixelCount[i];
        pixelHist[i] = sum / (SpriteWidth * SpriteHeight);
    }

    //specify start & end colors:
    RGB start = {0, 255, 51};
    RGB end = {255, 0, 153};

    int pIndex;
    for (int i = 0; i < SpriteWidth * SpriteHeight; i++)
    {
        pIndex = 4 * i;
        pixelArray_[pIndex] = start.red - start.red * pixelHist[iterations_[i]] + end.red * pixelHist[iterations_[i]];
        pixelArray_[pIndex + 1] = start.green - start.green * pixelHist[iterations_[i]] + end.green * pixelHist[iterations_[i]];
        pixelArray_[pIndex + 2] = start.blue - start.blue * pixelHist[iterations_[i]] + end.blue * pixelHist[iterations_[i]];
    }

    //consider deallocating elsewhere.....
    delete [] pixelCount;
    delete [] pixelHist;

}


const uint8_t* Mandelbrot::GetPixelArray()
{
    return pixelArray_;
}

const int Mandelbrot::GetColumn(int index)
{
    return int(index % SpriteWidth);
}

const int Mandelbrot::GetRow(int index)
{
    return int(index / SpriteWidth);
}


